進入前端這個變化多端的異世界也已一年半,
每每拿著新手 jQuery 雙手劍砍怪總覺得特別的笨重;
這時候就特別需要獲得 原生 JavaScript 的 效能Buff 加持!!
如果你也是打算從 jQuery 準備正式轉戰 原生JavaScript 的勇者,
歡迎一起組隊,經驗加倍! (笑
在這裡我寫的未必是最好的寫法,
若你也能有更好的寫法、想法或建議歡迎留言,
大家一起討論互相學習!
PS. 本次挑戰學習筆記是基於 Wes Bos 的 JavaScript30 挑戰課程:
https://javascript30.com/
作品 Demo 連結: 傳送門
作品目標:按下鍵盤上對應的按鍵,發出對應的音效,並顯示特效。
難易度:★☆☆☆☆
HTML 於此僅列出 A鍵 及其對應的音效:
<!-- 按鍵 -->
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<!-- 音效 -->
<audio data-key="65" src="sounds/clap.wav"></audio>
CSS 部分如果在 .key 上加入 .playing 則會有過度動畫產生:
.key {
// ...略
border: .4rem solid black;
transition: all .07s ease;
}
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
我們先來處理發出音效的功能,接著再來處理頁面動畫。
var keys = document.querySelectorAll('.key');
var audios = document.querySelectorAll('audio');
首先我們先將所有的 .key 及 audio 選取出來
在 JavaScript 選取器中你可能曾經聽說過 getElementById / ClassName / Tag…
但是現在出現了比 getElementById 效能更高且更方便的 querySelector!
而且對於 jQuery 使用者也可以快速上手;
其實概念就是等於 jQuery 的 “$” 字號
選取器內容寫法跟 CSS, jQuery 方法一模一樣!
是不是很方便呢!?
querySelector 有分為兩種:
1. querySelector - 只會選取搜尋到的第一個對象
2. querySelectorAll - 以陣列形式儲存所有符合的對象
這次是使用後者,所以如果打算針對單個目標進行使用,請使用遍歷或過濾。
// 鍵盤事件綁定
window.addEventListener('keydown', function(event){
findAudio(event);
});
此處的 addEventListener 近似於 jQuery 的 .on() 或者 .bind()
也就是綁定事件! 這次選擇綁定 keydown - 鍵盤下壓事件。
我們在此處透過 function 參數 event 來取得按鍵的詳細資訊。
因為在 HTML 當中,作者有給予鍵盤及音效相對應的 data-key,
所以我們在待會兒會透過 findAudio 函數取用 event 中的 .keyCode 部分。
// 播放對應音效
function findAudio(keyDownEvent){
audios.forEach(function(element){
if(keyDownEvent.keyCode == element.dataset.key){
element.currentTime = 0; //目前播放時間設定為 0
element.play(); //播放音效
findKey(keyDownEvent); //執行動畫函數
}
});
}
在此處我們將之前已經選取的 audio 陣列來做遍歷。
透過 element.dataset.key 來取得當下元素的 data-key 內的數字,
如果數字與按鍵事件的 .keyCode 相同,
就將音效時間從 0 秒開始播放並且執行 findKey 函數後退出。
// 對應按鍵 class 添加 .playing 改變畫面
function findKey(keyDownEvent){
keys.forEach(function(element){
if(keyDownEvent.keyCode == element.dataset.key){
element.classList.add('playing');
}
});
}
這一步也是根據使用者按下的案件 keyCode
去尋找匹配的 .key 元素。
若條件符合則添加 .playing 執行動畫。
// 對應按鍵事件綁定
keys.forEach(function(element){
element.addEventListener('transitionend', function(){
element.classList.remove('playing');
})
});
這裡綁定了一個不錯用的事件 "transitionend"
在過渡動畫完成之後立馬撤掉 .playing 類別回復成原樣,
這樣可以造成打鼓震動的錯覺